
extern crate libc;
use libc::c_int;
use libc::c_void;
use libc::c_char;
use std::ffi::CString;
use std::ffi::CStr;
use std::thread;
use std::time::Duration;
use serde_json::{Value as JsonValue};//Result as JsonResult
use crate::bcossdk::kisserror::KissError;
use libloading::{Library, Symbol};
use std::sync::mpsc::{Sender, RecvTimeoutError};
use std::sync::mpsc::Receiver;
use std::sync::{mpsc, Arc};
use std::os::raw::c_long;

#[cfg(feature = "bcos3sdk_ffi")]
#[repr(C)]
#[derive(Debug)]
pub struct bcos_sdk_c_struct_response
{
    error:i32,  // 返回状态, 0成功, 其他失败
    desc:*const c_char,  // 失败时描述错误信息
    data:*const c_void,   // 返回数据, error=0 时有效
    size: usize,  // 返回数据大小, error=0 时有效
    context:*const c_void  // 回调上下文,调用接口时传入的`context`参数
}
#[cfg(feature = "bcos3sdk_ffi")]
#[derive(Debug,Clone)]
pub struct BcosSDKResponse {
    error:i32,
    desc:String,
    data:String,
    size:usize,
    context_data :bcos_sdk_context_data
}
impl BcosSDKResponse {
    pub fn display(&self)
    {
        print!("data {}", self.data);
        if self.size >0 {
            let v: JsonValue = serde_json::from_str(self.data.as_str()).unwrap();
            println!("json string is : {}", serde_json::to_string_pretty(&v).unwrap());
        }else{
            println!("data is empty :[]");
        }
        println!(">>size {}, error  {} ,desc:{}",self.size,self.error,self.desc);
        println!("context>> seq:{},name:[{}],desc:[{}]",self.context_data.seq,self.context_data.name,self.context_data.desc)
    }

}

#[cfg(feature = "bcos3sdk_ffi")]
#[repr(C)]
#[derive(Debug,Default,Clone)]
pub struct bcos_sdk_context_data{
    pub seq:i32,  // 返回状态, 0成功, 其他失败
    pub name: String,
    pub desc:String,  // 描述

}
#[cfg(feature = "bcos3sdk_ffi")]
#[repr(C)]
#[derive(Debug)]
pub struct bcos_sdk_context
{  pub data:bcos_sdk_context_data,
   pub tx: Sender<BcosSDKResponse>,
   pub rx: Receiver<BcosSDKResponse>
}
impl bcos_sdk_context{
    pub fn display(&self){
        println!("context data:{},[{}],[{}]",self.data.seq,self.data.name,self.data.desc);
    }
}
impl bcos_sdk_context
{

    pub fn to_pointer(c:&Arc<Self>)->*const c_void{
        Box::into_raw(Box::new(c.clone())) as * const c_void
    }
    pub fn from_pointer(p:*const c_void)->Box<Arc<Self>>
    {
        unsafe {
            Box::from_raw(p as *mut Arc<Self>)
        }
    }
    pub fn create(seq:i32,name:&str,desc:&str)->Arc<Self>
    {
        let (tx,rx) = mpsc::channel();
        let data = bcos_sdk_context_data{
            seq:seq,
            name:name.to_string(),
            desc:desc.to_string()
        };


        let context = bcos_sdk_context{
                data:data,
                tx:tx,
                rx:rx
        };
        Arc::new(context)
    }
    pub fn fire(&self,resp: BcosSDKResponse){
        //thread::sleep(Duration::from_secs(5));
        let res= self.tx.send(resp);
        println!("fire send result {:?}",res);
    }
    pub fn wait(&self)->Result<BcosSDKResponse,RecvTimeoutError>{
        let res = self.rx.recv_timeout(std::time::Duration::from_secs(3));
        //println!("wait res {:?}",&res);
        res
    }
}

#[cfg(feature = "bcos3sdk_ffi")]
type BCOS3SDK_CALLBACK_FUNC =extern "C"  fn(resp:*const bcos_sdk_c_struct_response);
type BCOS3SDK_AMOP_SUB_CALLBACK_FUNC =extern "C"  fn(endpoint:*const c_char,seq:*const c_char,resp:*const bcos_sdk_c_struct_response);

#[cfg(feature = "bcos3sdk_ffi")]
#[link(name = "bcos-c-sdk")]
extern "C" {
    fn bcos_sdk_create_by_config_file(configfile: *const c_char)->*const c_void;
    fn bcos_sdk_start(sdk:*const c_void);
    fn bcos_sdk_stop(sdk:*const c_void);
    fn bcos_sdk_destroy(sdk:*const c_void);
    fn bcos_sdk_get_last_error_msg()-> *mut c_char;
    fn bcos_sdk_get_last_error()->c_int;
    fn bcos_rpc_get_group_info( sdk : *const  c_void,  group: *const c_char,
                                callback:BCOS3SDK_CALLBACK_FUNC,
                                context:*const  c_void);
    fn bcos_rpc_get_group_list( sdk: *const  c_void, callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_group_info_list( sdk: *const  c_void, callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_group_node_info( sdk: *const  c_void,group: *const c_char,node:*const c_char, callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_transaction(sdk: *const c_void, group:*const c_char, node:*const c_char, tx_hash:*const c_char , proof:c_int,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_transaction_receipt(sdk: *const c_void, group:*const c_char, node:*const c_char, tx_hash:*const c_char , proof:c_int,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_block_by_hash(sdk: *const c_void, group:*const c_char, node:*const c_char, block_hash:*const c_char , only_header:c_int,only_tx_hash:c_int,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_block_by_number(sdk: *const c_void, group:*const c_char, node:*const c_char,  block_number:c_long, only_header :c_int, only_tx_hash :c_int,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_block_hash_by_number(sdk: *const c_void, group:*const c_char, node:*const c_char,  block_number:c_long, callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_block_limit(sdk: *const c_void,group:*const c_char)->c_int;
    fn bcos_rpc_get_block_number(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_code(sdk: *const c_void,group:*const c_char,node:*const c_char,address:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_sealer_list(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_observer_list(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_pbft_view(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_pending_tx_size(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_sync_status(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_consensus_status(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_system_config_by_key(sdk: *const c_void,group:*const c_char,node:*const c_char,key:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_total_transaction_count(sdk: *const c_void,group:*const c_char,node:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_group_peers(sdk: *const c_void,group:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    fn bcos_rpc_get_peers(sdk: *const c_void,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void);
    //Event类接口
    fn bcos_event_sub_subscribe_event(sdk: *const c_void,group:*const c_char,param:*const c_char,callback:BCOS3SDK_CALLBACK_FUNC, context:*const  c_void)->*const c_char;
    fn bcos_event_sub_unsubscribe_event(sdk: *const c_void,group:*const c_char);

    //AMOP类sdk
    //void bcos_amop_subscribe_topic(void* sdk, char** topics, size_t count)
    fn bcos_amop_subscribe_topic(sdk: *const c_void,topics : *const  *const c_char, count:c_long) ;
    // void bcos_amop_subscribe_topic_with_cb(void* sdk, const char* topic, bcos_sdk_c_amop_subscribe_cb cb, void* context)
    fn bcos_amop_subscribe_topic_with_cb(sdk: *const c_void,topic : *const c_char, callback:BCOS3SDK_AMOP_SUB_CALLBACK_FUNC,context:*const  c_void) ;

}

#[cfg(feature = "bcos3sdk_ffi")]
extern  "C" fn amop_sub_callback(endpoint:*const c_char,seq:*const c_char,resp:*const bcos_sdk_c_struct_response)
{
    unsafe {
        let mut endpointStr = "".to_string();
        let mut seqStr = "".to_string();
        if !endpoint.is_null() {
            endpointStr  = CStr::from_ptr(endpoint.clone()).to_str().unwrap().to_string();
        }
        if !seq.is_null() {
            seqStr  = CStr::from_ptr(seq.clone()).to_str().unwrap().to_string();
        }
        println!("endpoint {},seq {}",endpointStr,seqStr);
    }
}
#[cfg(feature = "bcos3sdk_ffi")]
extern "C" fn query_callback(resp:*const bcos_sdk_c_struct_response){

    unsafe {
        let mut strdata = "".to_string();
        let mut strdesc = "".to_string();
        let size = (*resp).size;
        println!(">> size  is {}",size);
        if !(*resp).data.is_null() {
            let mut recvbuffer: Vec<u8> = Vec::with_capacity(size);
            ((*resp).data as *const c_char).copy_to(recvbuffer.as_mut_ptr() as *mut c_char,size);
            recvbuffer.set_len(size);
            strdata = String::from_utf8(recvbuffer).unwrap();

            /*println!("strdata {}",strdata);
            let v: JsonValue = serde_json::from_str(strdata.as_str()).unwrap();
            println!("json string is : {}",serde_json::to_string_pretty(&v).unwrap());
            */
        }

        if !(*resp).desc.is_null() {
            strdesc = CStr::from_ptr((*resp).desc.clone()).to_str().unwrap().to_string();
            //println!("desc is {:?}", strdesc);
        }
        let mut response = BcosSDKResponse {
            desc : strdesc,
            data:   strdata,
            error: (*resp).error,
            size: (*resp).size,
            context_data : bcos_sdk_context_data::default()
        };

        if !(*resp).context.is_null(){

            //let context =  context_from_void_p!((*resp).context);//*Box::from_raw(resp.context as *mut bcos_sdk_context);
            let context = Box::from_raw((*resp).context as *mut Arc<bcos_sdk_context>);
            println!(">> context: ({}),({}),({})",context.data.seq,context.data.name,context.data.desc);
            response.context_data = context.data.clone();
            context.fire(response);
        }


    }
}
struct Bcos3SDKWrap{
    pub sdk:*const c_void
}
#[cfg(feature = "bcos3sdk_ffi")]
fn load_bcos3sdk_lib()->Result<Bcos3SDKWrap,KissError>
{
    unsafe {
        let cfgfile = CString::new("./bcos3sdklib/bcos3config.ini").unwrap();
        let sdk = bcos_sdk_create_by_config_file(cfgfile.as_ptr());
        println!("sdk is {:?}",sdk);
        bcos_sdk_start(sdk);
        let wrap = Bcos3SDKWrap {
            sdk:sdk
        };
        Ok(wrap)
    }
}

type FN_BCOS_SDK_CREATE = fn(*const c_char) -> *mut ::libc::c_void;
pub fn test_native_lib()
{
    unsafe {
        let lib_fullpath="./libbcos-c-sdk.dll".to_string();
        let res = Library::new(lib_fullpath.as_str());
        println!("{:?}",&res);
        let nativelib = res.unwrap();
        let loadres = (&nativelib).get(b"bcos_sdk_create");
        println!("{:?}",&loadres);
        let func_create: Symbol<FN_BCOS_SDK_CREATE> = loadres.unwrap() ;
        println!("{:?}",func_create);
    }
}
pub fn test_bcos3sdk(){
    #[cfg(feature = "bcos3sdk_ffi")]
    test_bcos3sdk_ffi();
    #[cfg(feature = "bcos3sdk_native")]
    test_native_lib();
}
#[cfg(feature = "bcos3sdk_ffi")]
pub fn test_bcos3sdk_ffi(){
    let sdkwrap = load_bcos3sdk_lib().unwrap();
    unsafe {
        let mut seq = 100;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_group_list","efg");
         context.display();
        bcos_rpc_get_group_list( sdkwrap.sdk,
                                query_callback as BCOS3SDK_CALLBACK_FUNC,
                                //to_void_p!(context)
                                bcos_sdk_context::to_pointer(&context)
        );
        let status = context.wait();
        println!("wait status {:?}",status);
        status.unwrap().display();

        let groupname = CString::new("group").unwrap();
        //------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);
        context.display();
        let context = bcos_sdk_context::create(seq,"abcd","efgf");
        bcos_rpc_get_group_info(sdkwrap.sdk,
                                b"group".as_ptr() as *const c_char,//groupname.clone().as_ptr(),
                                query_callback as BCOS3SDK_CALLBACK_FUNC,
                                bcos_sdk_context::to_pointer(&context)
        );
        let status = context.wait();
        println!("wait status {:?}",status);
        status.unwrap().display();
        //thread::sleep(Duration::from_secs(2));*/
        //------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);
        let thash2 = CString::new("0xc0a367cb5d11f21fd51196e9683cbfc2b8cd33c2e86c559d67142152f5fa7ee5").unwrap();
        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_transaction","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_transaction(sdkwrap.sdk,groupname.clone().as_ptr(),0 as *const c_char,
                                 //thash1.as_ptr()
                                 "0xc0a367cb5d11f21fd51196e9683cbfc2b8cd33c2e86c559d67142152f5fa7ee5".as_ptr() as *const c_char,
                                 //thash2.as_ptr() ,
                                 0,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();
        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_peers","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_peers(sdkwrap.sdk,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();
        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_group_peers","efgf");
        context.display();
        //let arc_context = Arc::new(context);
        //let pcontext =
        bcos_rpc_get_group_peers(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();
        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_total_transaction_count","efgf");
        context.display();
        //let arc_context = Arc::new(context);
        //let pcontext =
        bcos_rpc_get_total_transaction_count(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_system_config_by_key","efgf");
        context.display();
        //let arc_context = Arc::new(context);
        //let pcontext =
        bcos_rpc_get_system_config_by_key(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 "key".as_ptr() as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_consensus_status","efgf");
        context.display();
        //let arc_context = Arc::new(context);
        //let pcontext =
        bcos_rpc_get_consensus_status(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();
        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_sync_status","efgf");
        context.display();
        //let arc_context = Arc::new(context);
        //let pcontext =
        bcos_rpc_get_sync_status(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);
        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_pending_tx_size","efgf");
        context.display();
        //let arc_context = Arc::new(context);
        //let pcontext =
        bcos_rpc_get_pending_tx_size(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();


        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_pbft_view","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_pbft_view(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

//--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_observer_list","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_observer_list(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_sealer_list","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_sealer_list(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();


        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_code","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_code(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 "0xc0a367cb5d11f21fd51196e9683cbfc2b8cd33c2e86c559d67142152f5fa7ee5".as_ptr() as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();


        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_block_number","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_block_number(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();


                //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_block_limit","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        let limit = bcos_rpc_get_block_limit(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
        );
        println!("limit is  {}",limit);


        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_block_hash_by_number","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_block_hash_by_number(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 1,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();


                //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_block_by_hash","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_block_by_hash(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 "0xb92f29d369161c8306342d41f6702d9ce12f0a8898d05b83b08f03b7334f1052".as_ptr() as *const c_char,
                                 0,
                                 0,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_transaction_receipt","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_transaction_receipt(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 "0xc0a367cb5d11f21fd51196e9683cbfc2b8cd33c2e86c559d67142152f5fa7ee5".as_ptr() as *const c_char,
                                 0,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_rpc_get_transaction","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_rpc_get_transaction(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 0 as *const c_char,
                                 "0xc0a367cb5d11f21fd51196e9683cbfc2b8cd33c2e86c559d67142152f5fa7ee5".as_ptr() as *const c_char,
                                 0,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();


        seq = seq+1;
        println!("----------- start seq: {}",seq);

        let context = bcos_sdk_context::create(seq,"bcos_event_sub_subscribe_event","efgf");
        //let arc_context = Arc::new(context);
        //let pcontext =
        context.display();
        bcos_event_sub_subscribe_event(sdkwrap.sdk,
                                 groupname.clone().as_ptr(),
                                 "param".as_ptr() as *const c_char,
                                 query_callback as BCOS3SDK_CALLBACK_FUNC,
                                  bcos_sdk_context::to_pointer(&context) );
        let status = context.wait();
        println!("wait result  {:?}",status);
        status.unwrap().display();

        bcos_event_sub_unsubscribe_event(sdkwrap.sdk,"param".as_ptr() as *const c_char);


        seq = seq+1;
        println!("----------- start seq: ,bcos_amop_subscribe_topic{}",seq);
        let guangzhou = CString::new("guangzhou003").unwrap();
        let shenzhen = CString::new("shenzhen0755").unwrap();
        let topics= vec!(guangzhou.as_ptr(),shenzhen.as_ptr() );
        bcos_amop_subscribe_topic(sdkwrap.sdk,topics.as_ptr(),2);
        println!("bcos_amop_subscribe_topic done");
        //--------------------------------------------------------------------------------------
        seq = seq+1;
        println!("----------- start seq: ,bcos_amop_subscribe_topic{}",seq);
        let context = bcos_sdk_context::create(seq,"bcos_amop_subscribe_topic_with_cb","efgf");
        let topic = CString::new("cbtest001").unwrap();
        bcos_amop_subscribe_topic_with_cb(sdkwrap.sdk,topic.as_ptr(),amop_sub_callback,bcos_sdk_context::to_pointer(&context) );
        println!("bcos_amop_subscribe_topic_with_cb done");


        println!("ready to quit");
        thread::sleep(Duration::from_secs(2));

        bcos_sdk_stop(sdkwrap.sdk);
        bcos_sdk_destroy(sdkwrap.sdk);
        println!("Ok to quit");
    }
}
